home *** CD-ROM | disk | FTP | other *** search
/ Info-Mac 3 / Info_Mac_1994-01.iso / Science / Gnuplot 3.5 / docs / doc2ipf.c < prev    next >
C/C++ Source or Header  |  1993-11-03  |  15KB  |  505 lines

  1. #ifndef lint
  2. static char *RCSid = "$Id: doc2ipf.c%v 3.50 1993/07/09 05:35:24 woo Exp $";
  3. #endif
  4.  
  5. /*
  6.  * doc2ipf.c  -- program to convert Gnuplot .DOC format to OS/2
  7.  * ipfc  (.inf/.hlp) format.
  8.  *
  9.  * Modified by Roger Fearick from doc2rtf by M Castro 
  10.  *
  11.  * usage:  doc2ipf gnuplot.doc gnuplot.itl
  12.  *
  13.  */
  14.  
  15. /* note that tables must begin in at least the second column to */
  16. /* be formatted correctly and tabs are forbidden */
  17.  
  18. #include <stdio.h>
  19. #include <ctype.h>
  20. #include <string.h>
  21. #include <stdlib.h>
  22. #include <malloc.h>
  23.  
  24. #define MAX_LINE_LEN    1024
  25. #define TRUE 1
  26. #define FALSE 0
  27.  
  28. struct LIST
  29. {
  30.     int level;
  31.     int line;
  32.     char *string;
  33.     struct LIST *next;
  34.     };
  35.  
  36. struct LIST *list = NULL;
  37. struct LIST *head = NULL;
  38.  
  39. struct LIST *keylist = NULL;
  40. struct LIST *keyhead = NULL;
  41.  
  42. struct TABENTRY { /* may have 3 column tables */
  43.         struct TABENTRY *next ;
  44.         char col[3][256] ;
  45.         } ;
  46.  
  47. struct TABENTRY table = {NULL} ;
  48. struct TABENTRY *tableins = &table ;
  49. int tablecols = 0 ;
  50. int tablewidth[3] = {0,0,0} ;        
  51. int tablelines = 0 ;
  52.  
  53. int debug = FALSE;
  54.  
  55. void parse();
  56. void refs();
  57. void convert();
  58. void process_line();
  59. int lookup();
  60.  
  61. main(argc,argv)
  62. int argc;
  63. char **argv;
  64. {
  65. FILE * infile;
  66. FILE * outfile;
  67.     if (argc==4 && argv[3][0]=='-' && argv[3][1]=='d')
  68.         debug = TRUE;
  69.  
  70.     if (argc != 3 && !debug) {
  71.         fprintf(stderr,"Usage: %s infile outfile\n", argv[0]);
  72.         return(1);
  73.     }
  74.     if ( (infile = fopen(argv[1],"r")) == (FILE *)NULL) {
  75.         fprintf(stderr,"%s: Can't open %s for reading\n",
  76.             argv[0], argv[1]);
  77.         return(1);
  78.     }
  79.     if ( (outfile = fopen(argv[2],"w")) == (FILE *)NULL) {
  80.         fprintf(stderr,"%s: Can't open %s for writing\n",
  81.             argv[0], argv[2]);
  82.     }
  83.     parse(infile);
  84.     convert(infile,outfile);
  85.     return(0);
  86. }
  87.  
  88. /* scan the file and build a list of line numbers where particular levels are */
  89. void parse(a)
  90. FILE *a;
  91. {
  92.     static char line[MAX_LINE_LEN];
  93.     char *c;
  94.     int lineno=0;
  95.     int lastline=0;
  96.  
  97.     while (fgets(line,MAX_LINE_LEN,a)) 
  98.     {
  99.     lineno++;
  100.     if (isdigit(line[0]))
  101.     {
  102.         if (list == NULL)    
  103.             head = (list = (struct LIST *) malloc(sizeof(struct LIST)));
  104.         else
  105.             list = (list->next = (struct LIST *) malloc(sizeof(struct LIST)));
  106.         list->line = lastline = lineno;
  107.         list->level = line[0] - '0';
  108.         list->string = (char *) malloc (strlen(line)+1);
  109.         c = strtok(&(line[1]),"\n");
  110.         strcpy(list->string, c);
  111.         list->next = NULL;
  112.     }
  113.     if (line[0]=='?')
  114.     {
  115.         if (keylist == NULL)    
  116.             keyhead = (keylist = (struct LIST *) malloc(sizeof(struct LIST)));
  117.         else
  118.             keylist = (keylist->next = (struct LIST *) malloc(sizeof(struct LIST)));
  119.         keylist->line = lastline;
  120.         keylist->level = line[0] - '0';
  121.         c = strtok(&(line[1]),"\n");
  122.         if( c == NULL || *c == '\0' ) c = list->string ;
  123.         keylist->string = (char *) malloc (strlen(c)+1);
  124.         strcpy(keylist->string, c);
  125.         keylist->next = NULL;
  126.     }
  127.     }
  128.     rewind(a);
  129.     }
  130.  
  131. /* look up an in text reference */
  132. int
  133. lookup(s)
  134. char *s;
  135. {
  136.     char *c;
  137.     char tokstr[MAX_LINE_LEN];
  138.     char *match; 
  139.     int l;
  140.  
  141.     strcpy(tokstr, s);
  142.  
  143.     /* first try the ? keyword entries */
  144.     keylist = keyhead;
  145.     while (keylist != NULL)
  146.     {
  147.         c = keylist->string;
  148.         while (isspace(*c)) c++;
  149.         if (!strcmp(s, c)) return(keylist->line);
  150.         keylist = keylist->next;
  151.         }
  152.  
  153.     /* then try titles */
  154.     match = strtok(tokstr, " \n\t");
  155.     l = 0; /* level */
  156.     
  157.     list = head;
  158.     while (list != NULL)
  159.     {
  160.         c = list->string;
  161.         while (isspace(*c)) c++;
  162.         if (!strcmp(match, c)) 
  163.         {
  164.             l = list->level;
  165.             match = strtok(NULL, "\n\t ");
  166.             if (match == NULL)
  167.             {
  168.                 return(list->line);
  169.                 }
  170.             }
  171.         if (l > list->level)
  172.             break;
  173.         list = list->next;
  174.         }
  175.     return(-1);
  176.     }
  177.  
  178. /* search through the list to find any references */
  179. void
  180. refs(l, f)
  181. int l;
  182. FILE *f;
  183. {
  184.     int curlevel;
  185.     char str[MAX_LINE_LEN];
  186.     char *c;
  187.  
  188.     /* find current line */
  189.     list = head;
  190.     while (list->line != l)
  191.         list = list->next;
  192.     curlevel = list->level;
  193.     list = list->next;        /* look at next element before going on */
  194.     while (list != NULL)
  195.     {
  196.         /* we are onto the next topic so stop */
  197.         if (list->level == curlevel)
  198.             break;
  199.         /* these are the next topics down the list */
  200.         if (list->level == curlevel+1)
  201.         {
  202.             c = list->string;
  203.             }
  204.         list = list->next;
  205.         }
  206.     }
  207.  
  208. void
  209. convert(a,b)
  210.     FILE *a,*b;
  211. {
  212.     static char line[MAX_LINE_LEN];
  213.     
  214.     /* generate rtf header */
  215.     fprintf(b,":userdoc.\n:prolog.\n");
  216.     fprintf(b,":title.GNUPLOT\n");
  217.     fprintf(b,":docprof toc=1234.\n:eprolog.\n");
  218.  
  219.     /* process each line of the file */
  220.         while (fgets(line,MAX_LINE_LEN,a)) {
  221.        process_line(line, b);
  222.        }
  223.  
  224.     /* close final page and generate trailer */
  225.     fprintf(b,"\n:euserdoc.\n");
  226. }
  227.  
  228. void
  229. process_line(line, b)
  230.     char *line;
  231.     FILE *b;
  232. {
  233.     static int line_count = 0;
  234.     static char line2[MAX_LINE_LEN];
  235.     static int last_line;
  236.     char hyplink1[64] ;
  237.     char *pt, *tablerow ;
  238.     int i;
  239.     int j;
  240.     static int startpage = 1;
  241.     char str[MAX_LINE_LEN];
  242.     char topic[MAX_LINE_LEN];
  243.     int k, l;
  244.     static int tabl=0;
  245.     static int para=0;
  246.     static int inquote = FALSE;
  247.     static int inref = FALSE;
  248.     static int intable = FALSE ; 
  249.     static int intablebut = FALSE ;
  250.     static FILE *bo= NULL, *bt = NULL ;
  251.  
  252.     line_count++;
  253.  
  254.     if( bo == NULL ) bo = b ;
  255.     i = 0;
  256.     j = 0;
  257.     while (line[i] != NULL)
  258.     {
  259.         switch(line[i])
  260.         {
  261.             case '$':
  262.                 if( intable && line[0] == '%' ) {                                    
  263.                    ++i ;
  264.                    if( line[i+1]=='$'|| line[i]=='x' || line[i]=='|'){
  265.                       while ( line[i] != '$' ) line2[j++]=line[i++] ;
  266.                       --j;
  267.                       }
  268.                    else {
  269.                        while( line[i] != '$' ) i++ ;
  270.                        if( line[i+1]==',' ) i++ ;
  271.                        if( line[i+1]==' ' ) i++ ;
  272.                        line2[j]=line[++i] ;
  273.                        }
  274.                    }
  275.                 break ;
  276.             case ':':
  277.                 strcpy( &line2[j], "&colon." ) ;
  278.                 j += strlen( "&colon." ) - 1 ;
  279.                 break ;
  280.  
  281.             case '&':
  282.                 strcpy( &line2[j], "&." ) ;
  283.                 j += strlen( "&." ) - 1 ;
  284.                 break ;
  285.                                 
  286.             case '\r':
  287.             case '\n':
  288.                 break;
  289.             case '`':    /* backquotes mean boldface or link */
  290.                 if ((!inref) && (!inquote))
  291.                 {
  292.                     k=i+1;    /* index into current string */
  293.                     l=0;    /* index into topic string */
  294.                     while ((line[k] != '`') && (line[k] != NULL))
  295.                     {
  296.                         topic[l] = line[k];
  297.                         k++;
  298.                         l++;
  299.                         }
  300.                     topic[l] = NULL;
  301.                     k = lookup(topic);
  302.                     if (k > 0)
  303.                     {
  304.                         sprintf( hyplink1, ":link reftype=hd res=%d.", k ) ;
  305.                         strcpy( line2+j, hyplink1 ) ;
  306.                         j += strlen( hyplink1 )-1 ;
  307.                         
  308.                         inref = k;
  309.                         }
  310.                     else
  311.                     {
  312.                         if (debug)
  313.                             fprintf(stderr,"Can't make link for \042%s\042 on line %d\n",topic,line_count);
  314.                         line2[j++] = ':';
  315.                         line2[j++] = 'h';
  316.                         line2[j++] = 'p';
  317.                         line2[j++] = '2';
  318.                         line2[j] = '.';
  319.                         inquote = TRUE;
  320.                         }
  321.                     }
  322.                 else
  323.                 {
  324.                     if (inquote && inref)
  325.                         fprintf(stderr, "Warning: Reference Quote conflict line %d\n", line_count);
  326.                     if (inquote)
  327.                     {
  328.                         line2[j++] = ':';
  329.                         line2[j++] = 'e';
  330.                         line2[j++] = 'h';
  331.                         line2[j++] = 'p';
  332.                         line2[j++] = '2';
  333.                         line2[j] = '.';
  334.                         inquote = FALSE;
  335.                         }
  336.                     if (inref)
  337.                     {
  338.                         /* must be inref */
  339.                         line2[j++] = ':';
  340.                         line2[j++] = 'e';
  341.                         line2[j++] = 'l';
  342.                         line2[j++] = 'i';
  343.                         line2[j++] = 'n';
  344.                         line2[j++] = 'k';
  345.                         line2[j] = '.';
  346.                         inref = 0;
  347.                         }
  348.                 }
  349.                 break;
  350.             default:
  351.                 line2[j] = line[i];
  352.             }
  353.         i++;
  354.         j++;
  355.         line2[j] = NULL;
  356.         }
  357.  
  358.     i = 1;
  359.  
  360.     switch(line[0]) {        /* control character */
  361.        case '?': {            /* interactive help entry */
  362.                 if( intable ) intablebut = TRUE ;
  363.                break;
  364.        }
  365.        case '@': {            /* start/end table */
  366.                   intable = !intable ;  
  367.                   if( intable ) {
  368.                     tablelines = 0;
  369.                     tablecols = 0 ;
  370.                     tableins = &table ;
  371.                     for(j=0;j<3;j++)tablewidth[j]=0 ;
  372.                     }
  373.                   else { /* dump table */
  374.                     intablebut = FALSE ;
  375.                     tableins = table.next ;
  376.                     fprintf(b,":table cols=\'") ;
  377.                     for( j=0;j<3;j++)
  378.                         if(tablewidth[j]>0) fprintf(b," %d",tablewidth[j]);
  379.                     fprintf(b,"\'.\n") ;
  380.                     tableins=tableins->next ;     
  381.                     while( tableins != NULL ) {
  382.                         if( tableins->col[0][0] != '_' ) {
  383.                             fprintf(b,":row.\n" ) ;
  384.                             for( j=0;j<tablecols;j++) 
  385.                                 fprintf(b,":c.%s\n", tableins->col[j] ) ;
  386.                             }
  387.                         tableins = tableins->next ;
  388.                         }
  389.                     fprintf(b,":etable.\n") ;
  390.                     if( bt != NULL ) {
  391.                         rewind( bt ) ;
  392.                         while( fgets(str, MAX_LINE_LEN, bt) )
  393.                             fputs( str, b ) ; 
  394.                         fclose( bt ) ;
  395.                         remove( "doc2ipf.tmp" ) ;
  396.                         bt = NULL ;
  397.                         bo = b ;
  398.                         }
  399.                     }
  400.           break;            /* ignore */
  401.        }
  402.        case '#': {            /* latex table entry */
  403.           break;            /* ignore */
  404.        }
  405.        case '%': {            /* troff table entry */
  406.               if( intable ) {
  407.                     tablerow = line2 ;
  408.                     tableins->next = malloc( sizeof( struct TABENTRY ) ) ;
  409.                     tableins = tableins->next ;
  410.                     tableins->next = NULL ;
  411.                     j=0 ;
  412.                 while((pt=strtok( tablerow, "%@\n" ))!=NULL) {
  413.                     if( *pt != '\0' ) { /* ignore null columns */
  414.                         strcpy( tableins->col[j], pt ) ;
  415.                         k=strlen( pt ) ;
  416.                         if( k > tablewidth[j] ) tablewidth[j]=k ;
  417.                         ++j ;
  418.                         tablerow = NULL ;
  419.                         if( j > tablecols ) tablecols = j ;
  420.                         }
  421.                     }
  422.                 for( j; j<3; j++ ) tableins->col[j][0]='\0' ;        
  423.                 }
  424.           break;            /* ignore */
  425.        }
  426.        case '\n':            /* empty text line */
  427.             para = 0;
  428.             tabl = 0;
  429.             fprintf(bo,":p.");
  430.             break;
  431.        case ' ': {            /* normal text line */
  432.                   if( intable && ! intablebut ) break ;
  433.                   if( intablebut ) { /* indexed items in  table, copy
  434.                                       to file after table by saving in
  435.                                       a temp file meantime */
  436.                                 if( bt == NULL ) {
  437.                                     fflush(bo) ;
  438.                                     bt = fopen( "doc2ipf.tmp", "w+" ) ;
  439.                                     if( bt==NULL ) fprintf(stderr, "cant open temp\n" ) ;
  440.                                     else bo = bt ; 
  441.                                     }
  442.                         }
  443.                   if( intablebut && (bt==NULL )) break ;
  444.           if ((line2[1] == NULL) || (line2[1] == '\n'))
  445.           {
  446.                 fprintf(bo,":p."); 
  447.                 para = 0;
  448.                 }
  449.           if (line2[1] == ' ') 
  450.           {
  451.                 if (!tabl)
  452.                 {
  453.                     fprintf(bo,":p."); 
  454.                     }
  455.                   fprintf(bo,"%s",&line2[1]); 
  456.                 fprintf(bo,"\n.br\n");
  457.                 tabl = 1;
  458.                 para = 0;
  459.                 }
  460.           else
  461.           {
  462.                 if (!para)
  463.                 {
  464.                     para = 1;        /* not in para so start one */
  465.                     tabl = 0;
  466.                     }
  467.                   fprintf(bo,"%s \n",&line2[1]); 
  468.                 }
  469.                   fflush(bo) ;
  470.           break;
  471.        }
  472.        default: {
  473.           if (isdigit(line[0])) { /* start of section */
  474.                   if( intable ) {
  475.                       intablebut = TRUE ;
  476.                                 if( bt == NULL ) {
  477.                                     fflush(bo) ;
  478.                                     bt = fopen( "doc2ipf.tmp", "w+" ) ;
  479.                                     if( bt==NULL ) fprintf(stderr, "cant open temp\n" ) ;
  480.                                     else bo = bt ; 
  481.                                     }
  482.                                 }
  483.             if (!startpage)
  484.             {
  485.                 refs(last_line,bo);
  486.                 }
  487.             para = 0;                    /* not in a paragraph */
  488.             tabl = 0;
  489.             last_line = line_count;
  490.             startpage = 0;
  491. fprintf( stderr, "%d: %s\n", line_count, &line2[1] ) ;
  492.             k=lookup(&line2[2]) ;
  493. /*            if( k<0 ) fprintf(bo,":h%c.", line[0]=='1'?line[0]:line[0]-1);
  494.             else*/ fprintf(bo,":h%c res=%d.", line[0]=='1'?line[0]:line[0]-1,line_count);
  495.             fprintf(bo,&(line2[1])); /* title */
  496.             fprintf(bo,"\n:p." ) ;
  497.           } else
  498.             fprintf(stderr, "unknown control code '%c' in column 1, line %d\n",
  499.                 line[0], line_count);
  500.           break;
  501.        }
  502.     }
  503. }
  504.  
  505.